﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XTeam.Core.Interface;

namespace XTeam.Core.Helper
{
    public class TreeBuilder<T> where T : IClassifyEntity
    {
        private IClassifyEntity _root;
        private IList<T> _classiyfCollection;

        public TreeBuilder(T root)
        {
            this._root = root;
        }

        public TreeBuilder(T root, IList<T> classiyfCollection)
        {
            root.ClassId = root.ClassId < 1 ? 0 : root.ClassId;
            this._root = root;
            this._classiyfCollection = classiyfCollection;
        }

        public void Builder()
        {
            this.Builder(_classiyfCollection);
        }

        public void Builder(IList<T> classiyfCollection)
        {
            _classiyfCollection = classiyfCollection;
            foreach (IClassifyEntity item in classiyfCollection)
            {
                item.ClassId = item.ClassId < 1 ? -1 : item.ClassId;
            }

            Action<IClassifyEntity, IEnumerable<T>> tree = null;
            tree = (IClassifyEntity root, IEnumerable<T> children) =>
            {
                root.Children = new List<IClassifyEntity>();
                foreach (var child in children)
                {
                    child.Parent = root;
                    child.Floor = root.Floor + 1;
                    child.Path = string.Format("-{0}-{1}-", root.Path, child.ClassId);
                    child.Path = child.Path.Trim('-');
                    root.Children.Add(child);
                    tree(child, _classiyfCollection.Where(i => i.ParentId == child.ClassId));
                }
            };
            tree(_root, _classiyfCollection.Where(i => i.ParentId == _root.ClassId));
        }

        public void Update(ref IList<T> entities)
        {
            foreach (IClassifyEntity item in entities)
            {
                item.ParentId = item.ParentId <= 0 ? 0 : item.ParentId;
                var parent = _classiyfCollection.SingleOrDefault(i => i.ClassId == item.ParentId);
                if (item.ParentId > 0 && parent == null)
                {
                    throw new Exception("父类不存在");
                }
                var current = _classiyfCollection.SingleOrDefault(i => i.ClassId == item.ClassId);

                if (current != null)
                {
                    if (item.ParentId > 0 && string.Format("-{0}-", parent.Path).IndexOf(string.Format("-{0}-", current.Path)) >= 0)
                    {
                        throw new Exception("不能设置父类为自己或自己的子类");
                    }
                    _classiyfCollection.Remove(current);
                    _classiyfCollection.Add((T)item);
                }
                else
                {
                    throw new Exception("分类不存在");
                }
            }
            this.Builder(_classiyfCollection);
        }

        public void Append(ref IList<T> entities)
        {
            foreach (IClassifyEntity item in entities)
            {
                item.ParentId = item.ParentId <= 0 ? 0 : item.ParentId;
                item.ClassId = item.ClassId < 1 ? -1 : item.ClassId;

                var parent = _classiyfCollection.SingleOrDefault(i => i.ClassId == item.ParentId);

                if (item.ParentId > 0 && parent == null)
                {
                    throw new Exception("父类不存在");
                }
                _classiyfCollection.Add((T)item);
            }
            this.Builder(_classiyfCollection);
        }
    }
}
